// 版权所有2011 Go作者。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

// 包crypto收集公共加密常量。
package crypto

import (
	"hash"
	"io"
	"strconv"
)

// 哈希标识在另一个应用程序中实现的加密哈希函数
// 包裹
type Hash uint

// HashFunc只返回h的值，以便Hash实现SignerOpts。
func (h Hash) HashFunc() Hash {
	return h
}

func (h Hash) String() string {
	switch h {
	case MD4:
		return "MD4"
	case MD5:
		return "MD5"
	case SHA1:
		return "SHA-1"
	case SHA224:
		return "SHA-224"
	case SHA256:
		return "SHA-256"
	case SHA384:
		return "SHA-384"
	case SHA512:
		return "SHA-512"
	case MD5SHA1:
		return "MD5+SHA1"
	case RIPEMD160:
		return "RIPEMD-160"
	case SHA3_224:
		return "SHA3-224"
	case SHA3_256:
		return "SHA3-256"
	case SHA3_384:
		return "SHA3-384"
	case SHA3_512:
		return "SHA3-512"
	case SHA512_224:
		return "SHA-512/224"
	case SHA512_256:
		return "SHA-512/256"
	case BLAKE2s_256:
		return "BLAKE2s-256"
	case BLAKE2b_256:
		return "BLAKE2b-256"
	case BLAKE2b_384:
		return "BLAKE2b-384"
	case BLAKE2b_512:
		return "BLAKE2b-512"
	default:
		return "unknown hash value " + strconv.Itoa(int(h))
	}
}

const (
	MD4         Hash = 1 + iota // 导入golang.org/x/crypto/md4
	MD5                         // 导入加密/md5
	SHA1                        // 导入加密/sha1
	SHA224                      // 导入加密/sha256
	SHA256                      // 导入加密/sha256
	SHA384                      // 导入加密/sha512
	SHA512                      // 导入加密/sha512
	MD5SHA1                     // 没有执行；用于TLS RSA的MD5+SHA1
	RIPEMD160                   // 导入golang.org/x/crypto/ripemd160
	SHA3_224                    // 导入golang.org/x/crypto/sha3
	SHA3_256                    // 导入golang.org/x/crypto/sha3
	SHA3_384                    // 导入golang.org/x/crypto/sha3
	SHA3_512                    // 导入golang.org/x/crypto/sha3
	SHA512_224                  // 导入加密/sha512
	SHA512_256                  // 导入加密/sha512
	BLAKE2s_256                 // 导入golang.org/x/crypto/blake2s
	BLAKE2b_256                 // 导入golang.org/x/crypto/blake2b
	BLAKE2b_384                 // 导入golang.org/x/crypto/blake2b
	BLAKE2b_512                 // 导入golang.org/x/crypto/blake2b
	maxHash
)

var digestSizes = []uint8{
	MD4:         16,
	MD5:         16,
	SHA1:        20,
	SHA224:      28,
	SHA256:      32,
	SHA384:      48,
	SHA512:      64,
	SHA512_224:  28,
	SHA512_256:  32,
	SHA3_224:    28,
	SHA3_256:    32,
	SHA3_384:    48,
	SHA3_512:    64,
	MD5SHA1:     36,
	RIPEMD160:   20,
	BLAKE2s_256: 32,
	BLAKE2b_256: 32,
	BLAKE2b_384: 48,
	BLAKE2b_512: 64,
}

// Size返回给定哈希结果摘要的长度（以字节为单位）
// 作用它不需要链接所讨论的哈希函数
// 进入程序。
func (h Hash) Size() int {
	if h > 0 && h < maxHash {
		return int(digestSizes[h])
	}
	panic("crypto: Size of unknown hash function")
}

var hashes = make([]func() hash.Hash, maxHash)

// New返回一个新的hash。hash计算给定的hash函数。新恐慌
// 如果哈希函数未链接到二进制文件中。
func (h Hash) New() hash.Hash {
	if h > 0 && h < maxHash {
		f := hashes[h]
		if f != nil {
			return f()
		}
	}
	panic("crypto: requested hash function #" + strconv.Itoa(int(h)) + " is unavailable")
}

// Available报告给定的哈希函数是否链接到二进制文件中。
func (h Hash) Available() bool {
	return h < maxHash && hashes[h] != nil
}

// RegisterHash注册一个函数，该函数返回给定对象的新实例
// 散列函数。这是为了从中的init函数调用
// 实现哈希函数的包。
func RegisterHash(h Hash, f func() hash.Hash) {
	if h >= maxHash {
		panic("crypto: RegisterHash of unknown hash function")
	}
	hashes[h] = f
}

// PublicKey表示使用未指定算法的公钥。
type PublicKey interface{}

// PrivateKey表示使用未指定算法的私钥。
type PrivateKey interface{}

// 签名者是不透明私钥的接口，可用于
// 签名操作。例如，保存在硬件模块中的RSA密钥。
type Signer interface {
	// Public返回与不透明，
	// 私钥。
	Public() PublicKey

	// 签名-使用私钥签名摘要，可能使用来自
	// 兰德。对于RSA密钥，生成的签名应该是
	// PKCS#1 v1.5或PSS签名（如opts所示）。对于（EC）DSA
	// 密钥，它应该是一个顺序序列化的ASN.1签名结构。
	// None
	// 哈希实现SignerOpts接口，在大多数情况下，可以
	// 只需传入用作opt的哈希函数。符号也可能尝试
	// 类型断言选择其他类型以获得算法
	// 特定值。有关详细信息，请参阅每个软件包中的文档。
	// None
	// 请注意，当需要较大消息的哈希签名时，
	// 调用者负责散列较大的消息并传递
	// 要签名的哈希（作为摘要）和哈希函数（作为选项）。
	Sign(rand io.Reader, digest []byte, opts SignerOpts) (signature []byte, err error)
}

// SignerOpts包含与签名者签名的选项。
type SignerOpts interface {
	// HashFunc返回用于生成的哈希函数的标识符
	// 传递给Signer.Sign的消息，否则为零表示否
	// 散列已经完成。
	HashFunc() Hash
}

// 解密程序是一个不透明私钥的接口，可用于
// 非对称解密操作。例如RSA密钥
// 保存在硬件模块中。
type Decrypter interface {
	// Public返回与不透明，
	// 私钥。
	Public() PublicKey

	// 解密解密味精。opts参数应该适用于
	// 使用的原语。有关详细信息，请参阅每个实现中的文档
	// 细节。
	Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error)
}

type DecrypterOpts interface{}
